package com.eb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eb.constant.RedisConstant;
import com.eb.context.BaseContext;
import com.eb.domain.User;
import com.eb.dto.EditUserDto;
import com.eb.dto.RegisterUserDto;
import com.eb.exception.BaseException;
import com.eb.mapper.IUserMapper;
import com.eb.service.UserService;
import com.eb.vo.GetInfoUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Function;

@Service
public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements UserService {


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IUserMapper userMapper;

    /**
     * 用户注册
     * @param userDto
     * @return
     */
    @Override
    public boolean register(RegisterUserDto userDto) {
        String nickname = userDto.getNickname();
        //判断名称是否重复
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("nickname",nickname);
        User user1 = getOne(wrapper);
        if (user1 != null)
            return false;
        //初始化用户信息
        User user = BeanUtil.copyProperties(userDto, User.class);
        user.setCreateTime(LocalDateTime.now());
        user.setExperience(0);
        user.setStatus(1);
        user.setPermission(1);
        user.setLevel(1);
        boolean b = save(user);
        return b;
    }

    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public String login(String username, String password) {
        //1.校验用户名是否存在
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("nickname",username);
        User u1 = getOne(wrapper);
        if (u1 == null)
        {
            throw new BaseException("找不到该用户");
        }
        //2.检查密码是否正确
        wrapper.eq("password",password);
        User u2 = getOne(wrapper);
        if (u2 == null)
        {
            throw new BaseException("密码错误");
        }
        //3.将用户信息保存到Redis
        //3-1生成token 作为令牌
        String token = UUID.randomUUID().toString(true);
        //3-2将对象转为哈希存储
        Map<String, Object> userMap = BeanUtil.beanToMap(u2,new HashMap<>(),
                CopyOptions.create().setIgnoreNullValue(true)
                        .setFieldValueEditor(
                                new BiFunction<String, Object, Object>() {
                                    @Override
                                    public Object apply(String s, Object o) {
                                        if (o !=null)
                                        return o.toString();
                                        else
                                            return null;
                                    }
                                    @Override
                                    public <V> BiFunction<String, Object, V> andThen(Function<? super Object, ? extends V> after) {
                                        return BiFunction.super.andThen(after);
                                    }
                                }
                        )
        );
        //3-3存储
        stringRedisTemplate.opsForHash().putAll(RedisConstant.LOGIN_TOKEN+token,userMap);
        //3-4设置过期时间
        stringRedisTemplate.expire(RedisConstant.LOGIN_TOKEN+token,
                RedisConstant.LOGIN_USER_TTL, TimeUnit.MINUTES);
        //3-5返回
        return token;
    }

    /**
     * 获取当前用户信息
     * @param Id
     * @return
     */
    @Override
    public GetInfoUserVO getUserInfo(Integer Id) {
        //1.查询用户信息
        User user = userMapper.selectById(Id);

        //如果为null，则抛出不存在当前用户的异常
        if (user == null)
            throw new BaseException("此用户不存在");

        //2.将查询到的用户信息转为UserVO对象并返回
        return BeanUtil.copyProperties(user, GetInfoUserVO.class);
    }

    /**
     * 修改用户信息
     * @param userDto
     */
    @Override
    public void updateUserInfo(EditUserDto userDto) {
        //1.将userDto转为user对象
        User user = BeanUtil.copyProperties(userDto, User.class);
        user.setId(BaseContext.getCurrentId());
        //2.修改用户信息
        userMapper.updateById(user);
    }
}
